<!-- src/components/VideoSwiper.vue -->
<template>
  <div ref="containerRef" class="video-swiper" @wheel.passive="handleWheel" @touchstart="handleTouchStart"
    @touchmove="handleTouchMove" @touchend="handleTouchEnd">
    <div ref="wrapperRef" class="video-swiper__wrapper" :style="{ transform: `translateY(${translateY}px)` }">
      <div v-for="(video, index) in videos" :key="video.videoId" class="video-swiper__item" @click="handleClick(index)"
        @dblclick="handleVideoDoubleClick(index)">
        <video v-if="shouldRender(index)" :ref="el => setVideoRef(el, index)" :src="video.src" class="video-player"
          :muted="!shouldPlayWithSound" loop playsinline preload="auto" @error="onVideoError" @play="onVideoPlay"
          @pause="onVideoPause" />
        <div v-else class="video-placeholder"></div>

        <Transition name="scale-fade">
          <div v-show="showPauseIcon" class="Pause-icon">
            <Icon name="zantingtubiao" size="40" color="#fff" />
          </div>
        </Transition>

        <!-- 进度条 -->
        <div class="progressbar" :ref="el => setProgressbarRef(el, index)"
          @mousedown.stop="handleScrubStart(index, $event)" @touchstart.stop="handleScrubStart(index, $event)">
          <div class="progress" :style="{ width: `${(videoProgress[index] || 0) * 100}%` }"></div>
        </div>

        <!-- 插槽 -->
        <slot name="left" :video="video"></slot>
        <slot name="right" :video="video"></slot>
      </div>
      <!-- 👇 新增：Loading / No more 提示 -->
      <div v-if="videos.length > 0" class="video-swiper__loading">
        <div v-if="isLoadingMore" class="loading-text">加载中...</div>
        <div v-else-if="!hasMore" class="loading-text">没有更多内容啦~</div>
        <!-- 可选：加个 spinner 图标 -->
        <Icon v-if="isLoadingMore" name="jiazailoadding" color="red" size="24" />
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick, computed } from 'vue'
import Icon from '@/components/common/Icon.vue'
import { getVideoAPI } from '@/api/getvideo'
import { followFriendUserAPI } from '@/api/search'
import { useUserStore } from '@/stores/userinfo'
import { useSoundStore } from '@/stores/sound'

const soundStore = useSoundStore()
const shouldPlayWithSound = computed(() => soundStore.userInteracted)

const userStore = useUserStore()
const userId = computed(() => userStore.userInfo?.userId || '')

const videos = ref([])
const videoProgress = ref([])
const videoElements = ref([])

// 事件监听管理
const currentListeningIndex = ref(-1)
const progressHandlers = ref([])

// 👇 新增：系统暂停状态（用于声音弹窗）
const systemPaused = ref(false)

// 👇 新增：加载状态控制
const isLoadingMore = ref(false)
const hasMore = ref(true) // 假设初始有更多数据

async function fetchVideos(reset = false) {
  if (reset) {
    videos.value = []
    videoProgress.value = []
    progressHandlers.value = []
    hasMore.value = true
    isLoadingMore.value = false
  }

  if (isLoadingMore.value || !hasMore.value) return

  try {
    isLoadingMore.value = true
    const res = await getVideoAPI()
    if (res.code !== 200 || !Array.isArray(res.data)) {
      hasMore.value = false
      throw new Error('数据异常')
    }

    if (res.data.length === 0) {
      hasMore.value = false
      return
    }

    const videoList = res.data
      .map(str => {
        try {
          const parsed = JSON.parse(str)
          const { Video, WSLCNum } = parsed
          return {
            videoId: Video?.videoId,
            src: Video?.videoPath,
            userId: Video?.userId,
            userAvatar: Video?.userAvatar ? 'http://43.138.15.137:3000' + Video?.userAvatar : '',
            userNickname: Video?.userNickname,
            videoCover: Video?.videoCover,
            videoDesc: Video?.videoDesc,
            watchNum: WSLCNum?.watchNum || '0',
            likeNum: WSLCNum?.likeNum || '0',
            commentNum: WSLCNum?.commentNum || '0',
            shareNum: WSLCNum?.shareNum || '0',
            isLiked: false
          }
        } catch (e) {
          console.error('解析失败', e)
          return null
        }
      })
      .filter(Boolean)
    let videosWithFollowStatus = videoList;

    // if (userId.value) {
    //   videosWithFollowStatus = await Promise.all(
    //     videoList.map(async (video) => {
    //       try {
    //         const followRes = await followFriendUserAPI(userId.value, video.userId)
    //         const isFollowing = followRes.data === '关注成功'
    //         return { ...video, isFollowing }
    //       } catch (error) {
    //         console.error(`获取视频 ${video.videoId} 的关注状态失败:`, error)
    //         return { ...video, isFollowing: false }
    //       }
    //     })
    //   )
    // }
    if (userId.value) {
      const worker = new Worker(new URL('@/workers/api.worker.js', import.meta.url), { type: 'module' });
      worker.postMessage({
        currentUserId: userId.value,
        targetUserIds: videoList.map(video => video.userId),
      });

      videosWithFollowStatus = await new Promise((resolve, reject) => {
        worker.onmessage = (event) => {
          const followStatusMap = event.data; // 假设返回的是一个对象，key是userId，value是是否关注
          console.log('Worker 返回的关注状态:', followStatusMap);
          const updatedVideos = videoList.map(video => ({
            ...video,
            isFollowing: followStatusMap[video.userId] || false
          }));
          resolve(updatedVideos);
          worker.terminate();
        };

        worker.onerror = (error) => {
          console.error('Worker 错误:', error);
          reject(error);
          worker.terminate();
        };
      });
    }



    if (reset) {
      videos.value = videosWithFollowStatus
    } else {
      videos.value.push(...videosWithFollowStatus)
    }

    // 同步扩展进度和处理器数组
    const oldLen = videoProgress.value.length
    const newLen = videos.value.length
    if (newLen > oldLen) {
      videoProgress.value.push(...new Array(newLen - oldLen).fill(0))
      progressHandlers.value.push(...new Array(newLen - oldLen).fill(null))
    }
  } catch (err) {
    console.error('加载视频失败', err)
    hasMore.value = false
  } finally {
    isLoadingMore.value = false
  }
}

const emit = defineEmits(['change', 'double-click'])

const containerRef = ref(null)
const wrapperRef = ref(null)

const translateY = ref(0)
const startY = ref(0)
const startTranslateY = ref(0)
const isDragging = ref(false)
const lastClientY = ref(0)
const lastTimestamp = ref(0)
const velocity = ref(0)
const manuallyPaused = ref(new Set())

const getCurrentIndex = () => {
  const h = window.innerHeight
  const rawIndex = -translateY.value / h
  return Math.max(0, Math.min(Math.floor(rawIndex), videos.value.length - 1))
}

// 👇 新增：检查是否滑到底部最后一个视频
const checkAndLoadMore = () => {
  const currentIndex = getCurrentIndex()
  if (
    videos.value.length > 0 &&
    currentIndex === videos.value.length - 1 &&
    !isLoadingMore.value &&
    hasMore.value
  ) {
    // 延迟一点避免频繁触发（可选）
    setTimeout(() => {
      fetchVideos(false) // 不重置，追加
    }, 200)
  }
}

const showPauseIcon = computed(() => {
  const idx = getCurrentIndex()
  return manuallyPaused.value.has(idx)
})

const shouldRender = (index) => {
  const currentIndex = getCurrentIndex()
  return Math.abs(index - currentIndex) <= 1
}

const handleWheel = (e) => {
  if (isDragging.value) return
  const direction = e.deltaY > 0 ? 1 : -1
  const currentIndex = getCurrentIndex()
  const newIndex = Math.max(0, Math.min(currentIndex + direction, videos.value.length - 1))
  snapToIndex(newIndex)
}

const handleTouchStart = (e) => {
  isDragging.value = true//正在 拖拽
  const touch = e.touches[0]//获取第一个触摸点
  startY.value = touch.clientY//记录起始触摸点的Y坐标
  startTranslateY.value = translateY.value// 记录起始时的位移
  lastClientY.value = touch.clientY //记录上次触摸点的Y坐标
  lastTimestamp.value = Date.now()//记录上次时间戳
  velocity.value = 0 //重置速度

  //取消过渡效果
  if (wrapperRef.value) {
    wrapperRef.value.style.transition = 'none'
  }
}

const handleTouchMove = (e) => {
  if (!isDragging.value) return
  const touch = e.touches[0]
  const clientY = touch.clientY
  const now = Date.now()
  console.log(now)

  const deltaY = clientY - startY.value
  translateY.value = startTranslateY.value + deltaY

  const dt = now - lastTimestamp.value
  if (dt > 0 && dt < 100) {
    const dy = clientY - lastClientY.value
    velocity.value = dy / dt
  }

  lastClientY.value = clientY
  lastTimestamp.value = now
}

const handleTouchEnd = () => {
  if (!isDragging.value) return
  isDragging.value = false
  const targetIndex = getTargetIndex()
  snapToIndex(targetIndex)
}

const getTargetIndex = () => {
  const h = window.innerHeight
  const currentPos = -translateY.value
  const currentIndex = Math.floor(currentPos / h)
  const offset = currentPos - currentIndex * h
  const positionThreshold = h * 0.2

  if (velocity.value < 0 && offset > positionThreshold) {
    return Math.min(currentIndex + 1, videos.value.length - 1)
  }
  if (velocity.value > 0 && Math.abs(offset) > positionThreshold) {
    return Math.max(currentIndex - 1, 0)
  }
  return currentIndex
}

const createProgressHandler = (index) => {
  return () => {
    const video = videoElements.value[index]
    if (video && video.duration > 0) {
      videoProgress.value[index] = video.currentTime / video.duration
    }
  }
}

const snapToIndex = (index) => {
  velocity.value = 0
  const targetY = -index * window.innerHeight
  const currentY = translateY.value

  if (Math.abs(currentY - targetY) < 2) {
    translateY.value = targetY
    playCurrentVideo(index)
    return
  }

  if (wrapperRef.value) {
    wrapperRef.value.style.transition = 'none'
    void wrapperRef.value.offsetHeight
    wrapperRef.value.style.transition = 'transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94)'
  }

  translateY.value = targetY
  setTimeout(() => playCurrentVideo(index), 400)
}

const setVideoRef = (el, index) => {
  if (el) {
    videoElements.value[index] = el
  } else {
    videoElements.value[index] = null
  }
}

const onVideoError = (e) => {
  console.error('视频加载失败:', e.target.src)
}

const onVideoPlay = () => { }
const onVideoPause = () => { }

const playCurrentVideo = (index) => {
  emit('change', index)

  // 检查是否需要加载更多
  checkAndLoadMore()

  if (currentListeningIndex.value !== -1 && currentListeningIndex.value !== index) {
    const prevVideo = videoElements.value[currentListeningIndex.value]
    const prevHandler = progressHandlers.value[currentListeningIndex.value]
    if (prevVideo && prevHandler) {
      prevVideo.removeEventListener('timeupdate', prevHandler)
    }
  }

  videoElements.value.forEach((el, i) => {
    if (el && i !== index) {
      el.pause()
    }
  })

  const currentVideo = videoElements.value[index]
  if (!currentVideo) return

  currentListeningIndex.value = index

  const handler = createProgressHandler(index)
  progressHandlers.value[index] = handler
  currentVideo.addEventListener('timeupdate', handler)
  if (!soundStore.userInteracted) {
    currentVideo.muted = true
  }
  if (!manuallyPaused.value.has(index)) {
    currentVideo.play().catch(err => {
      console.warn('自动播放失败:', err)
    })
  }
}

const togglePlayPause = () => {
  const currentIndex = getCurrentIndex()
  const video = videoElements.value[currentIndex]
  if (!video) return

  if (video.paused) {
    video.play().catch(() => { })
    manuallyPaused.value.delete(currentIndex)
  } else {
    video.pause()
    manuallyPaused.value.add(currentIndex)
  }
}

const lastClickTime = ref(0)
const lastClickIndex = ref(-1)

const handleVideoDoubleClick = (index) => {
  emit('double-click', index)
}

const handleClick = (index) => {
  const now = Date.now()
  if (index === lastClickIndex.value && now - lastClickTime.value < 300) {
    handleVideoDoubleClick(index)
    lastClickTime.value = 0
    lastClickIndex.value = -1
    return
  }

  if (index === getCurrentIndex()) {
    togglePlayPause()
  }

  lastClickTime.value = now
  lastClickIndex.value = index
}

const preventScroll = (e) => {
  if (containerRef.value?.contains(e.target)) {
    e.preventDefault()
  }
}

// ===== 进度条拖拽控制 =====
const isScrubbing = ref(false)
const progressbarRefs = ref([])

const setProgressbarRef = (el, index) => {
  if (el) progressbarRefs.value[index] = el
}

const handleScrubMove = (e) => {
  if (!isScrubbing.value) return
  e.preventDefault()
  e.stopPropagation()

  const clientX = e.touches ? e.touches[0].clientX : e.clientX
  const currentIndex = getCurrentIndex()
  const bar = progressbarRefs.value[currentIndex]
  if (!bar) return

  const rect = bar.getBoundingClientRect()
  let percent = (clientX - rect.left) / rect.width
  percent = Math.max(0, Math.min(1, percent))
  videoProgress.value[currentIndex] = percent
}

const handleScrubEnd = (e) => {
  if (!isScrubbing.value) return
  isScrubbing.value = false

  const clientX = e?.changedTouches?.[0]?.clientX ?? e?.clientX
  const currentIndex = getCurrentIndex()
  const bar = progressbarRefs.value[currentIndex]
  let percent = videoProgress.value[currentIndex] || 0

  if (bar && clientX !== undefined) {
    const rect = bar.getBoundingClientRect()
    percent = (clientX - rect.left) / rect.width
    percent = Math.max(0, Math.min(1, percent))
  }

  const video = videoElements.value[currentIndex]
  if (video && video.duration) {
    video.currentTime = percent * video.duration
    if (!manuallyPaused.value.has(currentIndex)) {
      video.play().catch(() => { })
    }
  }

  document.removeEventListener('mousemove', handleScrubMove)
  document.removeEventListener('mouseup', handleScrubEnd)
  document.removeEventListener('touchmove', handleScrubMove, { passive: false })
  document.removeEventListener('touchend', handleScrubEnd)
}

const handleScrubStart = (index, e) => {
  if (index !== getCurrentIndex()) return
  e.stopPropagation()
  e.preventDefault()
  isScrubbing.value = true

  document.addEventListener('mousemove', handleScrubMove)
  document.addEventListener('mouseup', handleScrubEnd)
  document.addEventListener('touchmove', handleScrubMove, { passive: false })
  document.addEventListener('touchend', handleScrubEnd)
}

// ===== 对外暴露方法 =====
const pauseCurrentVideo = () => {
  const index = getCurrentIndex()
  const video = videoElements.value[index]
  if (video && !video.paused) {
    video.pause()
    systemPaused.value = true
  }
}

const resumeCurrentVideo = () => {
  systemPaused.value = false
  const index = getCurrentIndex()
  const video = videoElements.value[index]
  if (video && !manuallyPaused.value.has(index)) {
    video.muted = !soundStore.userInteracted
    video.play().catch(err => {
      console.warn('恢复播放失败:', err)
    })
  }
}

const refresh = async () => {
  await fetchVideos(true) // reset = true
  if (videos.value.length > 0) {
    nextTick(() => {
      snapToIndex(0)
    })
  }
}

defineExpose({
  pauseCurrentVideo,
  resumeCurrentVideo,
  refresh,
  getCurrentVideo() {
    const index = getCurrentIndex()
    return videoElements.value[index]
  }
})

onMounted(() => {
  document.addEventListener('touchmove', preventScroll, { passive: false })
  systemPaused.value = false
  fetchVideos(true).then(() => {
    if (videos.value.length > 0) {
      nextTick(() => {
        snapToIndex(0)
      })
    }
  })
})

onUnmounted(() => {
  document.removeEventListener('touchmove', preventScroll)

  videoElements.value.forEach((el, i) => {
    const handler = progressHandlers.value[i]
    if (el && handler) {
      el.removeEventListener('timeupdate', handler)
    }
  })
})
</script>

<style scoped lang="scss">
.video-swiper {
  @include fixed-top;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: #000;

  &__loading {
    height: 60px; // 固定高度，避免布局抖动
    @include flex-center;
    color: #fff;
    font-size: 14px;
    opacity: 0.8;
  }

  .loading-text {
    text-align: center;
  }

  &__wrapper {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    position: relative;
  }

  &__item {
    flex: 0 0 100%;
    position: relative;
    min-height: 100vh;
    @include flex-center;
  }

  .Pause-icon {
    @include absolute-center;
  }

  .video-player {
    width: 100%;
    height: 100%;
  }

  .progressbar {
    position: absolute;
    bottom: 55px;
    left: 50%;
    transform: translateX(-50%);
    width: 96%;
    height: 5px;
    background-color: rgba(255, 255, 255, 0.5);
    border-radius: 2px;

    .progress {
      height: 100%;
      background-image: $gradient-color;
      border-radius: 2px;
      width: 0;
      transition: width 0.1s linear;
    }
  }
}

.scale-fade-enter-active,
.scale-fade-leave-active {
  transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275),
    opacity 0.3s ease-in-out;
}

.scale-fade-enter-from,
.scale-fade-leave-to {
  opacity: 0;
  transform: scale(0.5);
}

.scale-fade-enter-to,
.scale-fade-leave-from {
  opacity: 1;
  transform: scale(1);
}
</style>